{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import itertools\n",
    "import random\n",
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Individual:\n",
    "    def __init__(self, genetype=None, phenotype=None, fitness=None):\n",
    "        self.genetype = genetype\n",
    "        self.phenotype = phenotype\n",
    "        self.fitness = fitness\n",
    "        \n",
    "    def __str__(self):\n",
    "        return '{0},{1},{2}'.format(self.genetype, self.phenotype, self.fitness)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = ['{:06b}'.format(i) for i in range(64)]\n",
    "y = ['{:06b}'.format(i) for i in range(64)]\n",
    "pop_set = [''.join(i) for i in itertools.product(x,y)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "110100111110,(3.253968253968255, 4.841269841269842),None\n"
     ]
    }
   ],
   "source": [
    "pop_size = 20\n",
    "parents_pop = [Individual() for i in range(pop_size)]\n",
    "\n",
    "# phenotype\n",
    "def phenotype(genetype):\n",
    "    x = int(genetype[:6],2)\n",
    "    y = int(genetype[6:],2)\n",
    "#     print(x,y)\n",
    "    return -5 + 10*x/63, -5+10*y/63\n",
    "\n",
    "# initialize - genetype\n",
    "genetypes = random.choices(pop_set,k=pop_size)\n",
    "\n",
    "for i in range(pop_size):\n",
    "    parents_pop[i].genetype = genetypes[i]\n",
    "    parents_pop[i].phenotype = phenotype(genetypes[i])\n",
    "\n",
    "print(parents_pop[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "011011111111,(-0.7142857142857144, 5.0),8.547671643848346 010001110110,(-2.3015873015873014, 3.571428571428571),8.7918738178711\n",
      "010000100001,(-2.4603174603174605, 0.23809523809523814),12.021018002363892 010110010011,(-1.507936507936508, -1.9841269841269842),12.339297809784112\n",
      "011011111111,(-0.7142857142857144, 5.0),8.547671643848346 110010110000,(2.9365079365079367, 2.6190476190476186),9.84518440689528\n",
      "011011111111,(-0.7142857142857144, 5.0),8.547671643848346 100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934\n",
      "010001110110,(-2.3015873015873014, 3.571428571428571),8.7918738178711 010011110011,(-1.9841269841269842, 3.095238095238095),11.658656016486592\n",
      "001010111111,(-3.412698412698413, 5.0),6.854028796672987 011011111111,(-0.7142857142857144, 5.0),8.547671643848346\n",
      "011100010100,(-0.5555555555555554, -1.8253968253968256),13.336991225382477 010011011110,(-1.9841269841269842, -0.23809523809523814),14.06522136060307\n",
      "110101101101,(3.412698412698413, 2.1428571428571432),9.485002078268435 100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934\n",
      "011100010100,(-0.5555555555555554, -1.8253968253968256),13.336991225382477 110101101101,(3.412698412698413, 2.1428571428571432),9.485002078268435\n",
      "011100010100,(-0.5555555555555554, -1.8253968253968256),13.336991225382477 010011110011,(-1.9841269841269842, 3.095238095238095),11.658656016486592\n",
      "110101101101,(3.412698412698413, 2.1428571428571432),9.485002078268435 100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934\n",
      "101110010001,(2.3015873015873014, -2.3015873015873014),10.630632354175301 110011010110,(3.095238095238095, -1.507936507936508),10.489444731239972\n",
      "110100001110,(3.253968253968255, -2.7777777777777777),9.279838715712238 010011011110,(-1.9841269841269842, -0.23809523809523814),14.06522136060307\n",
      "011100010100,(-0.5555555555555554, -1.8253968253968256),13.336991225382477 100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934\n",
      "101110010001,(2.3015873015873014, -2.3015873015873014),10.630632354175301 100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934\n",
      "011110001100,(-0.23809523809523814, -3.0952380952380953),11.744071594870363 110100001110,(3.253968253968255, -2.7777777777777777),9.279838715712238\n",
      "110100001110,(3.253968253968255, -2.7777777777777777),9.279838715712238 110010110000,(2.9365079365079367, 2.6190476190476186),9.84518440689528\n",
      "100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934 111100010111,(4.523809523809524, -1.3492063492063493),7.9959031727594985\n",
      "110101101101,(3.412698412698413, 2.1428571428571432),9.485002078268435 110010110000,(2.9365079365079367, 2.6190476190476186),9.84518440689528\n",
      "000111110000,(-3.888888888888889, 2.6190476190476186),8.60372677063818 010011110011,(-1.9841269841269842, 3.095238095238095),11.658656016486592\n",
      "010011011110,(-1.9841269841269842, -0.23809523809523814),14.06522136060307 110100001110,(3.253968253968255, -2.7777777777777777),9.279838715712238\n",
      "011110001100,(-0.23809523809523814, -3.0952380952380953),11.744071594870363 001010111111,(-3.412698412698413, 5.0),6.854028796672987\n",
      "010000100001,(-2.4603174603174605, 0.23809523809523814),12.021018002363892 110010110000,(2.9365079365079367, 2.6190476190476186),9.84518440689528\n",
      "010011011110,(-1.9841269841269842, -0.23809523809523814),14.06522136060307 110100111110,(3.253968253968255, 4.841269841269842),7.342339026320392\n",
      "010011011110,(-1.9841269841269842, -0.23809523809523814),14.06522136060307 110011010110,(3.095238095238095, -1.507936507936508),10.489444731239972\n",
      "010000100001,(-2.4603174603174605, 0.23809523809523814),12.021018002363892 101110010001,(2.3015873015873014, -2.3015873015873014),10.630632354175301\n",
      "010011011110,(-1.9841269841269842, -0.23809523809523814),14.06522136060307 110010110000,(2.9365079365079367, 2.6190476190476186),9.84518440689528\n",
      "110010110000,(2.9365079365079367, 2.6190476190476186),9.84518440689528 010000100001,(-2.4603174603174605, 0.23809523809523814),12.021018002363892\n",
      "110010110000,(2.9365079365079367, 2.6190476190476186),9.84518440689528 011110001100,(-0.23809523809523814, -3.0952380952380953),11.744071594870363\n",
      "011011111111,(-0.7142857142857144, 5.0),8.547671643848346 110100001110,(3.253968253968255, -2.7777777777777777),9.279838715712238\n",
      "111100010111,(4.523809523809524, -1.3492063492063493),7.9959031727594985 110100111110,(3.253968253968255, 4.841269841269842),7.342339026320392\n",
      "011110001100,(-0.23809523809523814, -3.0952380952380953),11.744071594870363 111100010111,(4.523809523809524, -1.3492063492063493),7.9959031727594985\n",
      "010001110110,(-2.3015873015873014, 3.571428571428571),8.7918738178711 111100010111,(4.523809523809524, -1.3492063492063493),7.9959031727594985\n",
      "011110001100,(-0.23809523809523814, -3.0952380952380953),11.744071594870363 010110010011,(-1.507936507936508, -1.9841269841269842),12.339297809784112\n",
      "010000100001,(-2.4603174603174605, 0.23809523809523814),12.021018002363892 011100010100,(-0.5555555555555554, -1.8253968253968256),13.336991225382477\n",
      "110100111110,(3.253968253968255, 4.841269841269842),7.342339026320392 010000100001,(-2.4603174603174605, 0.23809523809523814),12.021018002363892\n",
      "111100010111,(4.523809523809524, -1.3492063492063493),7.9959031727594985 001010111111,(-3.412698412698413, 5.0),6.854028796672987\n",
      "010001110110,(-2.3015873015873014, 3.571428571428571),8.7918738178711 010000100001,(-2.4603174603174605, 0.23809523809523814),12.021018002363892\n",
      "011100010100,(-0.5555555555555554, -1.8253968253968256),13.336991225382477 011110001100,(-0.23809523809523814, -3.0952380952380953),11.744071594870363\n",
      "110101101101,(3.412698412698413, 2.1428571428571432),9.485002078268435 010011110011,(-1.9841269841269842, 3.095238095238095),11.658656016486592\n",
      "110101101101,(3.412698412698413, 2.1428571428571432),9.485002078268435 101110010001,(2.3015873015873014, -2.3015873015873014),10.630632354175301\n",
      "110100111110,(3.253968253968255, 4.841269841269842),7.342339026320392 100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934\n",
      "010110010011,(-1.507936507936508, -1.9841269841269842),12.339297809784112 011100010100,(-0.5555555555555554, -1.8253968253968256),13.336991225382477\n",
      "010001110110,(-2.3015873015873014, 3.571428571428571),8.7918738178711 110011010110,(3.095238095238095, -1.507936507936508),10.489444731239972\n",
      "101110010001,(2.3015873015873014, -2.3015873015873014),10.630632354175301 110100111110,(3.253968253968255, 4.841269841269842),7.342339026320392\n",
      "100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934 010110010011,(-1.507936507936508, -1.9841269841269842),12.339297809784112\n",
      "011011111111,(-0.7142857142857144, 5.0),8.547671643848346 100100011110,(0.7142857142857144, -0.23809523809523814),16.190357841087934\n",
      "111100010111,(4.523809523809524, -1.3492063492063493),7.9959031727594985 110100001110,(3.253968253968255, -2.7777777777777777),9.279838715712238\n",
      "011110001100,(-0.23809523809523814, -3.0952380952380953),11.744071594870363 111100010111,(4.523809523809524, -1.3492063492063493),7.9959031727594985\n",
      "000100100100,(-4.365079365079366, 0.7142857142857144),8.624003348904573 000111110000,(-3.888888888888889, 2.6190476190476186),8.60372677063818\n"
     ]
    }
   ],
   "source": [
    "\n",
    "def ackley(x,y):\n",
    "    return math.e - 20*math.exp(-0.2*math.sqrt((x*x+y*y)/2))-math.exp((math.cos(2*math.pi*x)+math.cos(2*math.pi*y))/2)\n",
    "\n",
    "\n",
    "def fitness():\n",
    "    for indv in parents_pop:\n",
    "        value = -ackley(*indv.phenotype)\n",
    "        assert value >= 0\n",
    "        indv.fitness = value\n",
    "    \n",
    "# 选出一对父代\n",
    "def selection_one(_sum):\n",
    "    rand = random.random()*_sum\n",
    "    f = parents_pop[0].fitness\n",
    "    k = 0\n",
    "    while f < rand:\n",
    "        k += 1\n",
    "        f += parents_pop[k].fitness\n",
    "    return k\n",
    "\n",
    "def selection():\n",
    "    _sum = 0\n",
    "    for indv in parents_pop:\n",
    "        _sum += indv.fitness\n",
    "    j = selection_one(_sum)\n",
    "    k = selection_one(_sum)\n",
    "    #不能自己交配\n",
    "    while k == j:\n",
    "        j = selection_one(_sum)\n",
    "    \n",
    "    return parents_pop[j],parents_pop[k]\n",
    "    \n",
    "    \n",
    "    \n",
    "# test = phenotype('010111011010')\n",
    "# print(test)\n",
    "# ackley(*test)\n",
    "fitness()\n",
    "# for indv in parents:\n",
    "#     print(indv)\n",
    "for i in range(50):\n",
    "    couple = selection()\n",
    "    print(couple[0],couple[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n",
      "(<__main__.Individual object at 0x00000244F9EA0E10>, <__main__.Individual object at 0x00000244F9EA0EF0>)\n"
     ]
    }
   ],
   "source": [
    "def cross(parents):\n",
    "    rand = random.randrange(1,len(parents[0].genetype)-1)# 保证有交叉，限制范围\n",
    "    # print(parents[0].genetype, parents[1].genetype)\n",
    "    child1_gene = parents[0].genetype[:rand] + parents[1].genetype[rand:]\n",
    "    child2_gene = parents[1].genetype[:rand] + parents[0].genetype[rand:]\n",
    "    # print(child1_gene, child2_gene)\n",
    "    child1 = Individual(child1_gene, phenotype(child1_gene))\n",
    "    child2 = Individual(child2_gene, phenotype(child2_gene))\n",
    "    return child1, child2\n",
    "    \n",
    "\n",
    "indv1 = Individual('011000111010',(-1.1904761904761907, 4.206349206349206),9.43413478471696)\n",
    "indv2 = Individual('001001001101',(-3.571428571428571, -2.9365079365079363),8.69247157080665)\n",
    "for i in range(20):\n",
    "    print(cross((indv1,indv2)))\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "011000111010,None,None 001001001001,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001101001101,None,None\n",
      "111000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "001000111010,None,None 001001001101,None,None\n",
      "011010111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 000001001101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001000101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000111010,None,None 001001000101,None,None\n",
      "011000111010,None,None 001001101101,None,None\n",
      "011000111010,None,None 001001001101,None,None\n",
      "011000110010,None,None 001001001101,None,None\n"
     ]
    }
   ],
   "source": [
    "mutate_rate = 0.02\n",
    "def mutate(children_pop):\n",
    "    for child in children_pop:\n",
    "        new_genetype = []\n",
    "        for bit in child.genetype:\n",
    "            rand = random.random()\n",
    "            if rand < mutate_rate: # mutate\n",
    "                if bit == '1':\n",
    "                    new_genetype.append('0')\n",
    "                else:\n",
    "                    new_genetype.append('1')\n",
    "            else:\n",
    "                new_genetype.append(bit)\n",
    "        child.genetype = ''.join(new_genetype)\n",
    "            \n",
    "for i in range(20):\n",
    "    indv1 = Individual('011000111010')\n",
    "    indv2 = Individual('001001001101')\n",
    "    mutate([indv1,indv2])\n",
    "    print(indv1, indv2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
